package com.example.jetpackcomposebasic

import androidx.compose.foundation.BorderStroke
import androidx.compose.foundation.background
import androidx.compose.foundation.horizontalScroll
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Card
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.Layout
import androidx.compose.ui.layout.Placeable
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp

@Preview
@Composable
fun PreviewSampleGrid() {

    SampleGrid(
        listOf(
            "hello",
            "are you ok",
            "science",
            "books",
            "math",
            "where are you",
            "don't you worry",
            "I'm fine",
            "It's worth",
            "what are you doing",
            "I'm learning jetpack"
        )
    )
}

@Composable
fun SampleGrid(strList: List<String>) {

    Row(
        modifier = Modifier
            .background(color = Color.LightGray)
            // 开启水平左右滑动
            .horizontalScroll(rememberScrollState())
    ) {


        StaggeredGrid(Modifier.padding(5.dp), 3) {
            repeat(times = strList.size) {
                GridItem(strList[it], Modifier.padding(2.dp))
            }
        }
    }
}

/**
 * Staggered 交错
 * 交错网格
 */
@Composable
fun StaggeredGrid(
    modifier: Modifier = Modifier,
    rowCount: Int,
    composable: @Composable () -> Unit
) {

    Layout(composable, modifier) { measureables, constrain ->


        val placeables = measureables.map { it.measure(constrain) }

        var row = 0
        var column = 0

        val rowWidths = IntArray(rowCount)

        placeables.forEachIndexed { index, placeable ->

            // 计算行号
            val rowNumber = index % rowCount
            // 累加这一行的宽度
            rowWidths[rowNumber] += placeable.width
        }


        val maxWidth = rowWidths.maxOf { it }

        // 一定要计算并设置所有元素的最大宽度
        // 不然超出屏幕范围，程序会抛出异常并闪退
        layout(maxWidth, constrain.maxHeight) {

            placeables.forEachIndexed { index, placeable ->


                placeable.place(
                    calculateXLocation(column, row, rowCount, placeables),
                    calculateYLocation(column, row, rowCount, placeables)
                )

                row++

                if (row == rowCount) {
                    row = 0
                    column++
                }
            }

        }
    }
}

/**
 * 根据行列计算该元素所在行左边的所有 Placeable 宽度之和
 */
fun calculateXLocation(column: Int, row: Int, rowCount: Int, placeables: List<Placeable>): Int {
    if (column == 0) {
        return 0
    }

    val index = (column - 1) * rowCount + row
    return placeables[index].width + calculateXLocation(column - 1, row, rowCount, placeables)
}

/**
 * 根据行列计算该元素所在列上面的所有 Placeable 高度之和
 * */
fun calculateYLocation(column: Int, row: Int, rowCount: Int, placeables: List<Placeable>): Int {
    if (row == 0) {
        return 0
    }
    var height = 0
    for (i in 0..<row) {
        val index = column * rowCount + row
        height += placeables[index].height
    }

    return height
}


@Preview
@Composable
fun PrevGridItem() {
    GridItem(name = "吃饭", modifier = Modifier.padding(top = 30.dp))

}

@Composable
fun GridItem(name: String, modifier: Modifier) {


    Card(
        modifier = modifier,
        border = BorderStroke(color = Color.Gray, width = Dp.Hairline),
        shape = RoundedCornerShape(8.dp) // 圆角有多圆
    ) {
        Row(modifier = Modifier.padding(5.dp)) {
            Box(
                modifier = Modifier
                    .size(16.dp, 16.dp)
                    .background(MaterialTheme.colorScheme.secondary)
            )
            Spacer(modifier = Modifier.width(8.dp))
            Text(text = name)
        }
    }

}